package mirrormonkey.core.server;

import java.util.HashMap;
import java.util.Map;

import mirrormonkey.core.module.CoreModule;
import mirrormonkey.framework.EntityProvider;
import mirrormonkey.framework.ServerSyncAppState;
import mirrormonkey.framework.entity.SyncEntity;
import mirrormonkey.util.IdGenerator;

import com.jme3.network.MessageConnection;

public class ServerCoreModule extends CoreModule {

	protected final IdGenerator idGenerator;

	protected final Map<MessageConnection, ServerConnectionInfo> connectionData;

	private final DummyMappingStack dummyStack;

	public ServerCoreModule(ServerSyncAppState appState) {
		super(appState);
		idGenerator = new IdGenerator();
		idGenerator.reserve(EntityProvider.NULL_ID);
		connectionData = new HashMap<MessageConnection, ServerConnectionInfo>();
		this.dummyStack = new DummyMappingStack(this);
	}

	public ServerEntityData getData(SyncEntity entity) {
		ServerEntityData data = (ServerEntityData) entity.getData();
		if (data != null) {
			return data;
		}
		return new ServerEntityData(this, idGenerator.generateAndReserve(),
				entity);
	}

	@Override
	public ServerConnectionInfo getData(MessageConnection connection) {
		ServerConnectionInfo data = connectionData.get(connection);
		if (data != null) {
			return data;
		}
		return new ServerConnectionInfo((ServerSyncAppState) appState,
				connection);
	}

	public MappingStack getStack(SyncEntity entity,
			ServerEntityData dataOrDummy, MessageConnection connection) {
		return getDummyStack().findStack(entity, dataOrDummy, connection);
	}

	@Override
	public void update(float tpf) {
		for (ServerConnectionInfo i : connectionData.values()) {
			i.update(tpf);
		}
		super.update(tpf);
	}

	public DummyMappingStack getDummyStack() {
		return dummyStack;
	}

	protected void remove(MessageConnection connection) {
		connectionData.remove(connection);
	}

	protected void register(ServerConnectionInfo info) {
		connectionData.put(info.getConnection(), info);
	}

	public boolean hasData(MessageConnection connection) {
		return connectionData.containsKey(connection);
	}
}
